from django.shortcuts import render, HttpResponse, redirect, reverse
from web.forms.file import FolderModelForm, FileModelForm
from django.http import JsonResponse, FileResponse
from web import models
from django.forms import model_to_dict
from utils.tencent.cos import *
from django.views.decorators.csrf import csrf_exempt
import json
import requests
from django.utils.encoding import escape_uri_path
import time

data_list_status = 0


def file(request, project_id):
    parent_object = None
    global data_list_status
    data_list_status = request.tracer.project.use_space
    folder_id = request.GET.get('folder', '')
    if folder_id.isdecimal():
        parent_object = models.FileRepository.objects.filter(id=int(folder_id), file_type=2,
                                                             project=request.tracer.project).first()
    if request.method == "GET":
        if parent_object:
            file_object_list = models.FileRepository.objects.filter(project=request.tracer.project,
                                                                    parent=parent_object).order_by('-file_type')
        else:
            file_object_list = models.FileRepository.objects.filter(project=request.tracer.project,
                                                                    parent__isnull=True).order_by('-file_type')
        parent = parent_object
        breadcrumb_list = []

        while parent:
            breadcrumb_list.insert(0, model_to_dict(parent, ['id', 'name']))
            parent = parent.parent
        form = FolderModelForm(request, parent_object)
        context = {
            'form': form,
            'file_object_list': file_object_list,
            'breadcrumb_list': breadcrumb_list,
            'folder_object': parent_object,
        }
        return render(request, 'file.html', context)
    fid = request.POST.get('fid', '')
    edit_object = None
    if fid.isdecimal():
        edit_object = models.FileRepository.objects.filter(id=fid, file_type=2, project=request.tracer.project).first()
    if edit_object:
        form = FolderModelForm(request, parent_object, data=request.POST, instance=edit_object)
    else:
        form = FolderModelForm(request, parent_object, data=request.POST)
    if form.is_valid():
        form.instance.file_type = 2
        form.instance.parent = parent_object
        form.instance.update_user = request.tracer.user
        form.instance.project = request.tracer.project
        form.save()
        return JsonResponse({'status': True})

    return JsonResponse({'status': False, 'error': form.errors})


def file_delete(request, project_id):
    fid = request.GET.get('fid')
    delete_object = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()
    if delete_object.file_type == 1:
        # 删除文件，将容量还给当前项目的已使用空间
        if request.tracer.project.use_space - delete_object.file_size < 0:
            request.tracer.project.use_space = 0
        else:
            request.tracer.project.use_space -= delete_object.file_size
        # 保存
        request.tracer.project.save()
        # 在cos中删除文件
        delete_file(request.tracer.project.bucket, request.tracer.project.region, delete_object.key)
        delete_object.delete()
        return JsonResponse({'status': True})

    # 如果是一个文件夹就要考虑文件加起来的容量
    total_size = 0
    folder_list = [delete_object, ]
    key_list = []
    # 循环当前对象删除文件夹
    for folder in folder_list:
        row_list = models.FileRepository.objects.filter(project=request.tracer.project, parent=folder) \
            .order_by('-file_type')
        for row in row_list:
            # 如果是文件夹
            if row.file_type == 2:
                folder_list.append(row)
            # 如果是文件,就可以直接删除掉
            else:
                # 文件总大小
                total_size += row.file_size
                # 创建cos删除列表
                key_list.append({"Key": row.key})
    # 删除cos列表文件
    if key_list:
        delete_file_list(request.tracer.project.bucket, request.tracer.project.region, key_list)

    if total_size:
        request.tracer.project.use_space -= total_size
        request.tracer.project.save()
    delete_object.delete()
    return JsonResponse({'status': True})


@csrf_exempt
def cos_credential(request, project_id):
    file_list = json.loads(request.body.decode('utf-8'))
    # 上传文件大小
    total_size = 0
    # 上传单文件大小(M)
    per_file_size = request.tracer.price_policy.per_file_size * 1024 * 1024
    # 上传文件的总容量(G)
    project_space = request.tracer.price_policy.project_space * 1024 * 1024 * 1024

    for item in file_list:
        if item['size'] > per_file_size:
            msg = "单文件超出限制"
            return JsonResponse({'status': False, 'error': msg})
        total_size += item['size']

    if total_size + request.tracer.project.use_space > project_space:
        return JsonResponse({'status': False, 'error': "容量超过限制,请升级套餐。"})

    data = credential(request.tracer.project.bucket, request.tracer.project.region)

    return JsonResponse({'status': True, 'data': data})


@csrf_exempt
def file_post(request, project_id):
    form = FileModelForm(request, data=request.POST)
    # 当文件上传通过的时候
    if form.is_valid():
        # 通过ModelForm.save存储到数据库中的数据返回的instance对象，无法通过get_xx_display获取choice的中文
        # form.instance.file_type = 1
        # form.update_user = request.tracer.user
        # instance = form.save()
        # 添加成功之后，获取到新添加的那个对象（instance.id,instance.name,instance.file_type,instance.get_file_type_display()

        data_dict = form.cleaned_data

        # data_dict.pop('etag')
        data_dict.update({'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})

        instance = models.FileRepository.objects.create(**data_dict)
        # 项目的已使用空间：更新 (data_dict['file_size'])
        global data_list_status
        data_list_status = data_list_status + data_dict['file_size']
        request.tracer.project.use_space = data_list_status
        request.tracer.project.save()
        result = {
            'id': instance.id,
            'name': instance.name,
            'file_size': instance.file_size,
            'username': instance.update_user.username,
            'datetime': instance.update_datetime.strftime("%Y{}%m{} %d{} %H:%M").format('年', '月', '日'),
            # 'file_type': instance.get_file_type_display(),
            'download_url': reverse('file_download', kwargs={"project_id": project_id, 'file_id': instance.id})
        }
        return JsonResponse({'status': True, 'data': result})
    return JsonResponse({'status': False, 'data': "上传文件失败"})


# 文件下载
def file_download(request, project_id, file_id):
    file_object = models.FileRepository.objects.filter(id=file_id, project_id=project_id, file_type=1).first()

    res = requests.get(url=file_object.file_path)
    # # 文件分块处理(适用于大文件)
    # data = res.content
    # # 设置content_type 用于提示下载框
    # response = HttpResponse(data)
    # # 设置响应头:(下载文件名字，中文文件转义)
    # response['Content_Disposition'] = "attachment;filename={}".format(file_object.name)
    response = FileResponse(res)
    response['Content-Type'] = 'application/octet-stream'
    response['Content-Disposition'] = 'attachment;filename="{}"'.format(file_object.name)

    return response
